<?php

namespace app\admin\controller;

use app\common\controller\Backend;

use app\admin\model\User;
use think\Db;

/**
 * 订单管理
 *
 * @icon fa fa-circle-o
 */
class Order extends Backend
{

    /**
     * Order模型对象
     * @var \app\admin\model\Order
     */
    protected $model = null;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\Order;
        $this->view->assign("statusList", $this->model->getStatusList());
    }



    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */


    /**
     * 查看
     */
    public function index()
    {
        //当前是否为关联查询
        $this->relationSearch = true;
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if ($this->request->isAjax()) {
            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }
            list($where, $sort, $order, $offset, $limit) = $this->buildparams();

            $list = $this->model
                ->with(['user', 'project'])
                ->where($where)
                ->order($sort, $order)
                ->paginate($limit)->each(function($item) {
                    // 触发获取器
                    $item->handlers_badge = $item->handlers_badge;
                    return $item;
                });

            foreach ($list as $row) {
                $row->getRelation('user')->visible(['nickname']);
                $row->getRelation('project')->visible(['name']);
            }

            $result = array("total" => $list->total(), "rows" => $list->items());

            return json($result);
        }
        return $this->view->fetch();
    }

    /**
     * 添加订单
     */
    public function add()
    {
        if ($this->request->isPost()) {
            $params = $this->request->post("row/a");

            Db::startTrans();
            try {
                // 获取用户等级折扣
                $userDiscount = \app\admin\model\Order::getUserLevelDiscount($params['user_id']);

                // 计算最终折扣（订单折扣 × 用户等级折扣）
                $finalDiscount = bcmul($params['discount'], $userDiscount, 2);
                $params['discount'] = $finalDiscount;

                // 重新计算总金额（使用最终折扣）
                $totalAmount = bcmul(
                    bcmul($params['quantity'], $params['unit_price'], 2),
                    $finalDiscount,
                    2
                );
                $params['total_amount'] = $totalAmount;
                // 重新计算总金额（使用最终折扣）
                $params['total_amount'] = bcmul(
                    bcmul($params['quantity'], $params['unit_price'], 2),
                    $finalDiscount,
                    2
                );

                // 检查用户余额是否足够
                $user = \think\Db::name('user')->where('id', $params['user_id'])->lock(true)->find();
                if (!$user) {
                    $this->error('用户不存在');
                }

                if (bccomp($user['money'], $totalAmount, 2) < 0) {
                    $this->error('用户余额不足，当前余额：¥' . $user['money'] . '，订单金额：¥' . $totalAmount);
                }
                // 计算每个打手可分金额
                if (!empty($params['handler_ids'])) {
                    $handlerIds = is_array($params['handler_ids']) ? $params['handler_ids'] : explode(',', $params['handler_ids']);
                    $handlerCount = count($handlerIds);
                    if ($handlerCount > 0) {
                        $params['handler_amount'] = bcdiv($params['total_amount'], $handlerCount, 2);
                    } else {
                        $params['handler_amount'] = 0;
                    }
                } else {
                    $params['handler_amount'] = 0;
                }


                $params['order_sn'] = $this->model::generateOrderSn();
                $params['createtime'] = time();

                // 创建订单
                $result = $this->model->validate('Order.add')->save($params);
                if ($result === false) {
                    $this->error($this->model->getError());
                }

                $orderId = $this->model->id;

                // 扣除用户余额
                $newBalance = bcsub($user['money'], $totalAmount, 2);
                $updateResult = \think\Db::name('user')
                    ->where('id', $params['user_id'])
                    ->update([
                        'money' => $newBalance,
                        'updatetime' => time()
                    ]);

                if ($updateResult === false) {
                    $this->error('扣除用户余额失败');
                }

                // 记录用户资金流水
                $moneyLogData = [
                    'user_id' => $params['user_id'],
                    'money' => -$totalAmount,
                    'before' => $user['money'],
                    'after' => $newBalance,
                    'memo' => '支付订单：' . ($params['order_sn'] ?? 'ORD' . date('YmdHis')),
                    'createtime' => time()
                ];

                $moneyLogResult = \think\Db::name('user_money_log')->insert($moneyLogData);
                if (!$moneyLogResult) {
                    $this->error('记录资金流水失败');
                }

                if ($result === false) {
                    $this->error($this->model->getError());
                }

                $updateResult = Db::name('handler')
                    ->where('id','in', $handlerIds)
                    ->update([
                        'custom' => 1
                    ]);
                if ($updateResult === false) {
                    $this->error($this->model->getError());
                }

                Db::commit();
            } catch (ValidateException|PDOException|Exception $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }
            $this->success();

        }

        // 获取项目列表（包含单价信息）
        $projects = Db::name('project')
            ->where('status', 'in', ['1', '2'])
            ->field('id, name, default_price, unit')
            ->select();

        $this->view->assign('projects', $projects);

        // 获取用户列表
        $users = Db::name('user')->where('status', '1')->column('id,username', 'id');
        $this->view->assign('users', $users);

        // 获取打手列表
        $handlers = Db::name('handler')->where('status', '1')->column('id,name', 'id');
        $this->view->assign('handlers', $handlers);

        return $this->view->fetch();
    }

    /**
     * 修改订单状态
     */
    public function changeStatus($status,$ids)
    {
        if (!$this->request->isAjax()) {
            $this->error(__('No Results were found'));
        }
        Db::startTrans();
        try {
            $order = $this->model->find($ids);
            if (!$order) {
                throw new \Exception('订单不存在');
            }
            $originalStatus = $order->status;
            // 检查状态转换是否合法
            if (!$this->isValidStatusTransition($originalStatus, $status)) {
                throw new \Exception('状态转换不合法');
            }

            // 更新订单状态
            $order->status = $status;

            // 根据状态执行不同的业务逻辑
            switch ($status) {
                case 0: // 取消
                    $this->model->refundOrder($order);
                    break;
                case 3: // 完成
                    $this->model->completeOrder($order);
                    $order->end_time = time();
                    break;

                case 2: // 进行中
                    $order->start_time = time();
                    break;
            }

            $order->save();
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        $this->success("操作成功");
    }

    /**
     * 检查状态转换是否合法
     */
    protected function isValidStatusTransition($fromStatus, $toStatus)
    {
        $validTransitions = [
            0 => [1],      // 取消只能从待开始转换
            1 => [0, 2],   // 待开始可以转到取消或进行中
            2 => [3],      // 进行中可以转到完成
            3 => []        // 完成是最终状态
        ];

        return in_array($toStatus, $validTransitions[$fromStatus] ?? []);
    }

    /**
     * 重写edit方法，只允许修改部分字段
     */
    public function edit($ids = null)
    {
        if ($this->request->isPost()) {
            $params = $this->request->post("row/a");

            // 只允许修改的字段
            $allowedFields = ['remark', 'start_time', 'end_time'];
            $updateData = array_intersect_key($params, array_flip($allowedFields));

            $result = $this->model->where('id', $ids)->update($updateData);
            if ($result !== false) {
                $this->success();
            } else {
                $this->error($this->model->getError());
            }
        }

        $this->assignConfigs();
        return parent::edit($ids);
    }

    /**
     * 分配页面数据
     */
    protected function assignConfigs()
    {
        // 用户列表
        $users = Db::name('user')->where('status', 'normal')->column('id,username', 'id');
        $this->view->assign('users', $users);

        // 项目列表
        $projects = Db::name('project')->where('status', '1')->column('id,name', 'id');
        $this->view->assign('projects', $projects);

        // 打手列表
        $handlers = Db::name('handler')->where('status', 'normal')->column('id,name', 'id');
        $this->view->assign('handlers', $handlers);
    }

    /**
     * 批量更新
     *
     * @param $ids
     * @return void
     */
    public function multi($ids = null)
    {
        $params = $this->request->param('params');
        // 解析参数
        parse_str($params, $paramsArray);

        // 如果是状态变更操作
        if (isset($paramsArray['status'])) {
            Db::startTrans();
            try {
                $ids = $ids ?: $this->request->post('ids');
                $ids = is_array($ids) ? $ids : explode(',', $ids);
                foreach ($ids as $id) {
                    $this->changeStatus($id, $paramsArray['status']);
                }
                Db::commit();
                $this->success();
            } catch (\Exception $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }
        } else {
            // 其他批量操作调用父类方法
            parent::multi($ids);
        }
    }
}
